#include <cstdlib>
#include <iostream>
#include "Notes.h"
#include "Etudiant.h"
#include "MeilleureNote.h"
#include "GroupeSet.h"
#include "GroupeList.h"

using namespace std;

enum Mark
{
    C,
    C_PLUS,
    B,
    B_PLUS,
    A,
	A_PLUS, 	
};

int main(int argc, char *argv[])
{ 
    Notes<string,double> notes;
    notes.ajouterNote("inf1010",A);
    notes.ajouterNote("inf2145",A_PLUS);
    notes.ajouterNote("inf4589",B);

    //afficher le contenu de notes

	cout<<"Contenu de notes :\n\n";

    cout<<notes;

    cout << "\n*******************************" << endl;

    //executer trierNotes pour notes

	cout<<"\nNotes triees avec list<pair> :\n\n";

	notes.trierNotes();

    cout << "\n*******************************" << endl;

    //executer afficherNotesTriees pour notes

	cout<<"\nNotes triees avec priority_queue<pair> :\n\n";

    notes.afficherNotesTriees();

    cout << "\n*******************************" << endl;

    //afficher la moyenne de notes

    cout<<"\nLa moyenne des notes est de : "<<notes.calculMoyenne()<<endl<<endl;

    cout << "*******************************" << endl;

    Notes<string,double> notes2(notes);

    //afficher le contenu de notes2

    cout<<endl<<"Contenu de notes2 (copie de ''notes''):\n\n";

    cout<<notes2<<endl;

    cout << "*******************************" << endl;

    Etudiant AlbertEinstein("001","Einstein Albert",notes2);

    //Afficher les informations relatives a Albert Einstein

	cout<<AlbertEinstein;

    cout << "*******************************" << endl;

    //Afficher la Meilleure note prise par Albert Einstein ainsi que sa matiere
    //en utilisant le foncteur MeilleureNote

	MeilleureNote<string,double> best;

	cout<<endl<<"la meilleure note d Albert Einstein est ";
	cout<<best(AlbertEinstein.getCursus()).second<< " en ";
	cout<<best(AlbertEinstein.getCursus()).first<<endl<<endl;

    cout << "*******************************" << endl;

    //changer la meilleure note d'Albert Einstein en lui attribuant la note 1 dans la matiere ou il avait
    //obtenu la meilleure note

	cout<<endl << "On remplace sa meilleure note par '1' : "<<endl;

	AlbertEinstein.supprimerNote("inf2145");
	AlbertEinstein.ajouterNote("inf2145",1);

    cout<<endl<<"la meilleure note d Albert Einstein est ";
	cout<<best(AlbertEinstein.getCursus()).second<< " en ";
	cout<<best(AlbertEinstein.getCursus()).first<<endl<<endl;

    cout << "*******************************" << endl;

    //Afficher les informations d'Albert

    cout<<AlbertEinstein;

    cout << "*******************************" << endl;

    //supprimer la note precedente d'Albert

    AlbertEinstein.supprimerNote("inf2145");

	cout<<endl<<"On supprime la note precedante :"<<endl;

    //Afficher les informations d'Albert

    cout<<AlbertEinstein;

    cout << "*******************************" << endl;

    cout << "\nMaintenant nous allons saisir manuellement une note\n";
	
    //Saisir une note et l afficher
    string matiere;
	double note;
	
	cout <<endl<<"Matiere a ajouter : ";
	cin>>matiere;
	cout <<"Note attribuee a cette matiere : ";                                    
	cin>>note;
	AlbertEinstein.ajouterNote(matiere,note);
	cout<<AlbertEinstein;
	
    cout << "*******************************" << endl;                   
    cin.ignore();                                                                                 

	//cout<<endl<<endl<<AlbertEinstein.calculMoyenne()<<endl<<endl;        //DEBUG
	
    Etudiant e;
    cout << "\nSaisie etudiant:\n";

    //Saisir les donnees de e et l afficher

    cin>>e;
	cout<<e;                                                                      
    cout << "*******************************" << endl; 
    cout << "\nMaintenant nous allons manipuler les groupeSets\n";
    GroupeSet gs;

    //supprimer e de gs. Un message indiquant l impossibilite de suppression
    //doit etre affiche par la fonction de suppression
	
	cout<<"\nSupprimons 'e' du conteneur gs :\n\n";

	gs.supprimerEtudiant(e.getMatricule());
    
    cout << "\n*******************************" << endl;

    //ajouter e et Albert Einstein a gs et afficher gs

	cout<<"\nAjoutons les 2 etudiants crees a gs.\n";

    gs.ajouterEtudiant(&e);
	gs.ajouterEtudiant(&AlbertEinstein);

	cout<<endl<<"Contenu de gs :\n"<<gs;

    cout << "*******************************" << endl;

    // Afficher la moyenne de gs

	cout<<endl<<"La moyenne de gs est : "<<gs.calculMoyenne()<<endl<<endl;

    cout << "*******************************" << endl;

    //supprimer e de gs et afficher gs

	cout<<"\nSupprimons "<<e.getNomprenom()<<" du conteneur gs :\n\n";

	gs.supprimerEtudiant(e.getMatricule());

	cout<<endl<< "Contenu de gs :\n"<<gs;

    cout << "*******************************" << endl;

    //Ajouter dans gs la note ("Physique",20) pour AlbertEinstein et afficher gs

	cout<<endl<<"ajoutons la matiere 'Physique' a Einstein Albert avec la note '20'"<<"\n\nContenu de gs :\n";
	gs.ajouterNote("001","Physique",20);
	cout<<gs;

    cout << "*******************************" << endl;

    //supprimer le contenu de gs

	gs.supprimer();

	cout<<"\nOn vide le contenu de gs.\n\nContenu de gs :\n"<<gs;
    cout << "\n*******************************\n" << endl;
    cout << "Maintenant nous allons manipuler les groupelists\n";

    GroupeList ls;

    //ajouter e et Albert Einstein a ls et afficher le contenu de ls

	ls.ajouterEtudiant(&e);
	ls.ajouterEtudiant(&AlbertEinstein);

	cout<<"\nContenu de ls :\n";

	ls.afficherGroupe();

    cout << "\n*******************************\n" << endl;

    Etudiant e2(AlbertEinstein);

    //Changer le nom de e2 a "Cobb Douglas"

	cout<<"On ajoute un etudiant ayant le meme matricule qu un autre etudiant au groupe :\n\n";

    e2.setNomprenom("Cobb Douglas");

    //ajouter e2 a ls

	ls.ajouterEtudiant(&e2);

    //Un message indiquant l'impossibilite de l ajout
    //doit etre affiche par la fonction d ajout

	//MODIFICATION DE ajouterEtudiant POUR AFFICHER MESSAGE
    
	//afficher la moyenne de ls
    
	cout<<"\nMoyenne du groupe ls : "<<ls.calculMoyenne()<<endl;

    cout << "\n*******************************" << endl;
    //trier ls par moyenne

    ls.trierParMoyenne();

    cout << "*******************************" << endl;

    //trier ls par matricule

    ls.trierParMatricule();

    cout << "*******************************" << endl;
    
    cin.ignore();

	cout << "#nPress any caracter button and then the enter key to continue ...";

    cin.get();

    return EXIT_SUCCESS;
}
